﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include "CommandBase.h"
#include "ActionBase.h"
#include "Vector3d.h"

//command data type
enum EnCommandDataType
{
    CMDDATATYPE_INVALID = 0,
    CMDDATATYPE_FAMILY_NAME = 1,
    CMDDATATYPE_FAMILY_TYPE_NAME = 2,
    CMDDATATYPE_BUILTIN_CATEGORY_ID = 3,
    CMDDATATYPE_COMMAND_STRING = 4,
    CMDDATATYPE_COLUMN_TYPE = 5,
    CMDDATATYPE_FLOOR_TYPE = 6
};

//////////////////////////////////////////////////////////////////////////
//创建族实例的父Action，根据族类别的不同调用相应的子Action
//////////////////////////////////////////////////////////////////////////
class CreateGBMPFamilyInstanceAction : public gcmp::ActionBase
{
public:
    enum EnCreateFamilyMethod
    {
        CFM_NOT_DEFIND = 0,
        CFM_ONE_POINT,
        CFM_ONE_POINT_ON_HOST,
        CFM_TWO_POINT,
        CFM_THREE_POINT,     //三点创建，比如圆弧
        CFM_MULTIPLE_POINT,  //多条曲线的数据作为参数一起传给族文档，比如栏杆扶手
    };

public:
    CreateGBMPFamilyInstanceAction(const gcmp::ElementId& familyId, const std::wstring& familyType);
    virtual ~CreateGBMPFamilyInstanceAction();

// 继承自IAction的虚函数
public:
    virtual void InitAction(gcmp::IUiView* pCurrentView) override;
    virtual void OnChildActionFinished(gcmp::IUiView* pCurrentView, const gcmp::ActionOutput& childActionReturnParam) override;

private:
    //存储族的Id和族类型的名字
    gcmp::ElementId m_familyId;
    std::wstring m_familyType;
    EnCreateFamilyMethod m_createFamilyMethod;

};

//////////////////////////////////////////////////////////////////////////
//创建普通的点式族实例
//////////////////////////////////////////////////////////////////////////
class ActionCreateOnePointInstance : public gcmp::ActionBase
{
public:
    enum EnInstanceDirectionStatus
    {
        IDS_Not_Started             = 0,
        IDS_Getting_PlacePoint        = 1,
        IDS_Getting_DirectionPoint  = 2,
    };

public:
    ActionCreateOnePointInstance(const gcmp::ElementId& familyId, const std::wstring& familyType, bool continueCreate = true);
    virtual ~ActionCreateOnePointInstance();

    // 继承自IAction的虚函数
public:
    virtual void InitAction(gcmp::IUiView* pCurrentView) override;
    virtual void OnChildActionFinished(gcmp::IUiView* pCurrentView, const gcmp::ActionOutput& childActionReturnParam) override;

    //*************预览功能***************
public:
    void PreviewByPlacePoint(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& pos, const gcmp::Vector3d& mousePt);
    bool IsPreview() const { return m_isPreview;}
    void SetIsPreview(bool isPreview) { m_isPreview = isPreview; }

protected:
    void GettingInstancePlacePoint();

protected:
    bool m_isUserCancelled;
    bool m_isPreview;
    gcmp::Vector3d m_placePt;

    //存储族的Id和族类型的名字
    gcmp::ElementId m_familyId;
    std::wstring m_familyType; 

    bool m_continueCreate; //是否连续创建

    // 已经Picked到的点集, 按照Pick顺序存储
    std::vector<gcmp::Vector3d> m_pickedPoints;
};


//////////////////////////////////////////////////////////////////////////
//创建基于Host对象的门窗族
//////////////////////////////////////////////////////////////////////////
class ActionCreateOnePointInstanceOnHost : public gcmp::ActionBase
{
public:
    ActionCreateOnePointInstanceOnHost(const gcmp::ElementId& familyId, const std::wstring& familyType);
    virtual ~ActionCreateOnePointInstanceOnHost();

    // 继承自IAction的虚函数
public:
    virtual void InitAction(gcmp::IUiView* pCurrentView) override;
    virtual void OnChildActionFinished(gcmp::IUiView* pCurrentView, const gcmp::ActionOutput& childActionReturnParam) override;

    //*************预览功能***************
public:
    void PreviewByPlacePoint(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& pos, const gcmp::Vector3d& mousePt);
    bool IsPreview() const { return m_isPreview;}
    void SetIsPreview(bool isPreview) { m_isPreview = isPreview; }

private:
    void GettingInstancePlacePoint();
    bool CreateTempOpeningByOnePointOnHost(gcmp::IUiView* pCurrentView, const gcmp::Vector3d& pos);
    bool GetPickResult(gcmp::IDocument* pDocument, gcmp::IUiView* pCurrentView, const gcmp::Vector3d& pos, gcmp::IGraphicsNodeReference& gnodeReference) const;

private:
    bool m_isUserCancelled;
    bool m_isPreview;
    gcmp::Vector3d m_placePt;
    gcmp::OwnerPtr<gcmp::ISnap> m_snap;

    //存储族的Id和族类型的名字
    gcmp::ElementId m_familyId;
    std::wstring m_familyType;

    // 已经Picked到的点集, 按照Pick顺序存储
    std::vector<gcmp::Vector3d> m_pickedPoints;
};




namespace gcmp
{
    class CreateGBMPFamilyInstanceCmd : public CommandBase
    {
        DECLARE_SUPER(CommandBase);
    public:
        CreateGBMPFamilyInstanceCmd();
        virtual ~CreateGBMPFamilyInstanceCmd();

        // ICommand接口实现
    public:
        virtual gcmp::OwnerPtr<gcmp::IAction> ExecuteCommand(const gcmp::CommandParameters& cmdParams) override;

        virtual bool IsEnabled() const override;
        virtual bool IsVisible() const override;

        //默认不清选择集
        virtual bool ShouldClearSelectionBeforeExecution() const override { return true; }
    };

}





